<?php
/**
 * Класс-предок для всех обработчиков (хэндлеров)
 *
 * @package mumak
 * @subpackage core
 * @since 09.07.2007
 * @author Алексей Михайлов <amikhailov83@mail.ru>
 * @version $Id: Handler.php 150 2007-10-01 10:30:49Z sixtyone $
 */

/**
 * RL_Handler class
 *
 * @abstract
 * @package mumak
 * @subpackage core
 */
abstract class RL_Handler {

	/**
	 * Ссылка на объект RH
	 *
	 * @var RL_SiteRequestHandler
	 */
	public $rh;

	/**
	 * Контекст окружения
	 *
	 * @var RL_Context_Site
	 */
	public $ctx;

	/**
	 * Ссылка на запускающий объект
	 *
	 * @var RL_Module
	 */
	public $module;

	/**
	 * Ответ пользователю
	 *
	 * @var RL_Response
	 */
	protected $response;

	/**
	 * Параметры запуска
	 *
	 * @var array
	 */
	public $params;

	/**
	 * Список виджетов.
	 *
	 * @var array
	 * @access public
	 */
	public $widgets = array();

	/*
	 * Содержит в себе конфиг виджетов которые прибавятся к тем, что отправляются через getWidgetsConfig()
	 *
	 * @var array
	 */
	private $widgets_config = array();

	/**
	 * Конструктор обработчика (любого)
	 *
	 * @final
	 * @param DKModule $module запускающий модуль
	 * @param array $params параметры запуска
	 */
	final public function __construct( RL_Module $module , array $params = array() )
	{
		$this->module = $module;
		$this->rh     = $module->rh;
		$this->ctx    = $module->rh->ctx;
		$this->params = &$params;

		$this->rh->UseClass('Action_Node_TopMenu');
		$topMenu = new Action_Node_TopMenu( $this->rh );
		$this->ctx->mm->aa->template_data['top_menu_content'] = $topMenu->getMenuHtml();

		if ( isset($this->rh->ctx->mm->aa) ) {
			$info = $this->rh->ctx->mm->aa->getInfo();

			if ( isset($info['role']['name']) ) {
				$this->rh->ctx->mm->aa->template_data['user_role'] = $info['role']['name'];
			}
		}

		//print '<pre style="text-align:left;">'; print_r($this->ctx->mm->aa->template_data['user']['role']);exit;
	}

	public function getWidgetsConfig() {}

	protected function loadWidgets ($config)
	{
		$widgets = array();
		foreach ($config as $w_id => $v) {

			$w_name  = $v['name'];
			$w_config  = $v['params'];
			$w = widgets_create($w_name, $this);
			if (!$w) {
				// по каким-то причинам виджет не создался.
				// скорее всего кто-то удалил исходник виджета с сайта; это иногда случается
				// после апдейта. =)
				//
				// сделать виджет "Сундук" -- затычку, которая будет создаваться
				//    вместо глючного виджета и, возможно, выводить причину. Модератор
				//    сможет ее явно удалить (или оставить на месте до лучших времен).
				if ($w = widgets_create('ChestWidget', $this)) {
					$w->setParam('message', $w_name);
				}
			}
			if ($w) {
				$w->setParam('widget_id', $w_id);
				$w->setParam('params', $this->params);
				$w->setParam('widget_url', $this->getUrl() . '?wid='.urlencode($w_id));
				foreach ($w_config as $p_name => $p_value) {
					$w->setParam($p_name, $p_value);
				}
				$widgets[$w_id] = $w;
				$w->initWidget($this);
			}/* else {
			}*/
		}
		return $widgets;
	} // end of function initWidgets

	public function getUrl()
	/**
	 * Вернуть url для данного экшена.
	 *
	 * @access public
	 * @return string
	 */
	{
		$this->rh->useClass("RL_URLGenerator");
		$ug = new RL_URLGenerator($this->rh->router->getLastMatched());
		$ug->setRouter($this->rh->router);
		$ug->setParams($this->params);
		return $ug->generateUrl();
	} // end of function getUrl

	protected function init() {}
	protected function shutdown() {}

	public function addWidget(array $widget_conf) {
		$this->widgets_config[] = $widget_conf;
	}


	/**
	 * Выполняет метод и возвращет ответ
	 *
	 * @return RL_Response
	 */
	public function execute()
	{
		// всегда
		$this->init();

		// --- widgets --- {{{
		if ($wcfg = $this->getWidgetsConfig()) {

			// специально добавим таким образом чтобы не затереть ид-шники которые там идут ключами массива
			foreach ($this->widgets_config as $widget_conf) {
				$wcfg[] = $widget_conf;
			}

			$this->widgets = $this->loadWidgets($wcfg);
			if ( isset($this->ctx->rh->REQUEST['wid'])
				&& isset($this->widgets[$this->ctx->rh->REQUEST['wid']]))
			{
				$widget = $this->widgets[$this->ctx->rh->REQUEST['wid']];
			}
		}
		// --- widgets --- }}}

		$action = isset($widget) ? $widget : $this;

		// --- cpaint ajax --- {{{
		if ((isset($this->params['is_ajax']) && $this->params['is_ajax']==1) || isset($this->ctx->rh->REQUEST['cpaint_function'])) {

			// перед этим всем нужно бы зарегить переменные cpaint
			foreach ($action->ajax_functions as $func) {
				$this->ctx->cp->register( array ( &$action, $func ), $func );
			}

			$this->ctx->cp->start();
			$this->rh->response->setStatus(RL_OK);
			$response = $this->rh->response;
		// --- cpaint ajax --- }}}

		} else {

			$action->process($this->ctx->rh);
			if($action->response instanceof RL_Response) {
				$response = $action->response;
			} else {
				$response = $this->ctx->debug->error("Handler must return RL_Response object");
			}

		}

		$this->response = $response;
		$this->shutdown();
		return $response;
	}

	/**
	 * Функция запуска хэндлера. В ней устанавливается содержимое ответа
	 *
	 * @abstract
	 * @return void
	 */
	abstract protected function process();
}
?>
